package com.lrabbit.mybatisplus.generator.config;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.lrabbit.controller.BaseController;
import com.lrabbit.mybatisplus.generator.bean.GenConfig;
import com.lrabbit.mybatisplus.generator.bean.PathConfig;
import com.lrabbit.mybatisplus.generator.util.TempBootUtil;
import com.lrabbit.mybatisplus.generator.util.TempUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class DefaultConfig {

    public static void execute(DataSourceConfig dsc, GenConfig genConfig, boolean apiFlag) {
        // 【设置1】全局设置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        System.out.println(projectPath);
        // 设置boot输出目录
        String outputDir = projectPath + genConfig.getOutPutBootDir();
        // 设置api输出目录
        String apiOutputDir = projectPath + genConfig.getOutPutApiDir();
        gc.setOutputDir(outputDir);
        gc.setAuthor("common-generator");
        // 生成后是否打开资源管理器
        gc.setOpen(false);
        // 重新生成时文件是否覆盖
        gc.setFileOverride(true);
        // 自定义文件名,%s会自动填充表实体属性
        gc.setServiceName("%sService");
        // 实体类/mapper/xml统一添加DO
        gc.setEntityName("%sDO");
        gc.setMapperName("%sDOMapper");
        gc.setXmlName("%sDOMapper");
        // 主键策略 自增 注意要和数据库中表实际的主键生成策略一致
        gc.setIdType(IdType.ASSIGN_ID);
        gc.setDateType(DateType.ONLY_DATE);
        // 开启Swagger2模式
        gc.setSwagger2(true);
        // 是否在xml中添加二级缓存配置
        gc.setEnableCache(false);
        // xml ResultMap是否为Java实体类自动添加注释
        gc.setBaseResultMap(true);
        // xml ColumnList是否为Java实体类自动添加注释
        gc.setBaseColumnList(true);

        // 【设置2】包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent(genConfig.getPackageParentName());
        pc.setController("controller");
        pc.setService("service");
        pc.setEntity("entity");
        pc.setMapper("mapper");

        // 【设置3】策略配置
        StrategyConfig strategy = new StrategyConfig();
        // 设置命名策略
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 实体类是否为lombok模式
        strategy.setEntityLombokModel(true);
        // 是否为restController
        strategy.setRestControllerStyle(true);
        // 指定表名
        strategy.setInclude(genConfig.getInclude());
        if (genConfig.getTablePrefix() != null) {
            strategy.setTablePrefix(genConfig.getTablePrefix());
        }
        strategy.setEntitySerialVersionUID(true);

        // 设置逻辑删除字段，要和数据库中的字段名一致
        strategy.setLogicDeleteFieldName("del_flag");
        // 设置父类
        strategy.setSuperControllerClass(BaseController.class);

        // 【设置4】自动填充设置
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill modifyTime = new TableFill("modify_time", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(createTime);
        tableFills.add(modifyTime);
        strategy.setTableFillList(tableFills);

        // 乐观锁
        strategy.setVersionFieldName("version");

        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        mpg.setGlobalConfig(gc);
        mpg.setDataSource(dsc);
        mpg.setStrategy(strategy);
        mpg.setPackageInfo(pc);

        // 【设置5】模板路径
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setMapper("/templates/mapper.java.vm");
        templateConfig.setServiceImpl("/templates/serviceImpl.java.vm");
        templateConfig.setService("/templates/service.java.vm");
        templateConfig.setController("/templates/controller.java.vm");
        // xml采用自定义方式生成(改变路径)
        templateConfig.setXml(null);
        // 如果是boot方式生成，则controller不再生成
        if (!apiFlag) {
            templateConfig.setController(null);
        }
        mpg.setTemplate(templateConfig);

        PathConfig pathConfig = new PathConfig();
        // api 目录 com.lrabbit.common.user 转换为 com.lrabbit.common.api.user
        StringBuilder apiPathBuilder = new StringBuilder(pc.getParent()).
                replace(pc.getParent().lastIndexOf("."),
                        pc.getParent().lastIndexOf(".") + 1, ".api.");
        String apiPackageName = apiPathBuilder.toString();
        apiOutputDir = apiOutputDir + "\\" + apiPackageName.replaceAll("\\.", "\\\\");
        String apiOutPath = apiOutputDir;

        pathConfig.setApiOutputPath(projectPath);
        pathConfig.setApiPackageName(apiPackageName);
        pathConfig.setApiPackageReqName(apiPackageName + ".request");
        pathConfig.setApiPackageRespName(apiPackageName + ".response");
        List<FileOutConfig> fileOutConfigList;
        // 是否生成API目录
        if (apiFlag) {
            fileOutConfigList = TempUtil.initApiTemp(apiOutPath, outputDir, genConfig);
        } else {
            // 生成xml
            fileOutConfigList = TempBootUtil.initBootTemp(outputDir, genConfig);
        }

        // 【设置6】变量全局
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                Map<String, Object> mapF = new HashMap<String, Object>();
                mapF.put("path", pathConfig);
                this.setMap(mapF);
            }
        };
        cfg.setFileOutConfigList(fileOutConfigList);
        mpg.setCfg(cfg);

        // 执行
        mpg.execute();
    }
}
